home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / elk-2_0.lha / elk-2.0 / src / stab.elf.c < prev    next >
C/C++ Source or Header  |  1992-10-19  |  3KB  |  116 lines

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <libelf.h>
  5.  
  6. SYMTAB *
  7. Snarf_Symbols (lf)
  8.      int    lf;
  9. {
  10.     SYMTAB    *tab = NULL;
  11.     register SYM *sp, **nextp;
  12.     Elf        *elf_ptr;
  13.     Elf_Scn    *elf_scn_ptr = NULL, *symtab_scn_ptr = NULL;
  14.     Elf_Data    *elf_data_ptr = NULL;
  15.     Elf32_Ehdr    *elf_ehdr_ptr = NULL;
  16.     Elf32_Shdr    *elf_shdr_ptr = NULL,
  17.         *symtab_ptr = NULL;
  18.     size_t    elf_str_index, shstrndx;
  19.     char    *symbol_name, *section_name;
  20.  
  21.     if (elf_version(EV_CURRENT) == EV_NONE)
  22.       Primitive_Error("a.out file Elf version out of date");
  23.     if ((elf_ptr = elf_begin(lf, ELF_C_READ, (Elf *)NULL)) == NULL)
  24.       Primitive_Error ("can't elf_begin() a.out file");
  25.  
  26.     /* 
  27.      * get the elf header, so we'll know where to look for the section 
  28.      * names.
  29.      */
  30.     if ((elf_ehdr_ptr = elf32_getehdr(elf_ptr)) == NULL) {
  31.     Primitive_Error("no elf header in a.out file");
  32.     }
  33.     shstrndx = elf_ehdr_ptr->e_shstrndx;
  34.     /* look for the symbol and string tables */
  35.     while (elf_scn_ptr = elf_nextscn(elf_ptr, elf_scn_ptr)) {
  36.     if ((elf_shdr_ptr = elf32_getshdr(elf_scn_ptr)) == NULL)
  37.       Primitive_Error("can't get section header in a.out file");
  38.     if (elf_shdr_ptr->sh_type == SHT_STRTAB) {
  39.         /* 
  40.          * save the index to the string table for later use by 
  41.          * elf_strptr().
  42.          */
  43.         section_name = elf_strptr(elf_ptr, shstrndx,
  44.                       (size_t)elf_shdr_ptr->sh_name);
  45.         if (strcmp(section_name, ".strtab") == 0) {
  46.         elf_str_index = elf_ndxscn(elf_scn_ptr);
  47.         }
  48.     }
  49.     else if (elf_shdr_ptr->sh_type == SHT_SYMTAB) {
  50.         symtab_ptr = elf_shdr_ptr;
  51.         symtab_scn_ptr = elf_scn_ptr;
  52.     }
  53.     }
  54.     if (!symtab_ptr)
  55.       Primitive_Error("no symbol table in a.out file");
  56.     if (!elf_str_index)
  57.       Primitive_Error("no string table in a.out file");
  58.     /* 
  59.      * we've located the symbol table -- go through it and save the names 
  60.      * of the interesting symbols.
  61.      */
  62.     while (elf_data_ptr = elf_getdata(symtab_scn_ptr, elf_data_ptr)) {
  63.     char    *name = NULL;
  64.     int    symbol_count;
  65.     Elf32_Sym    *symbol_ptr = elf_data_ptr->d_buf;
  66.     Elf32_Sym    *current_symbol;
  67.  
  68.     tab = (SYMTAB *)Safe_Malloc (sizeof (SYMTAB));
  69.     tab->first = 0;
  70.     tab->strings = 0;
  71.     nextp = &tab->first;
  72.     for (symbol_count = 1;
  73.          /* < was <= in the version I received from the author, but
  74.           * the last entry seems to be bogus:
  75.           */
  76.          symbol_count < symtab_ptr->sh_size / symtab_ptr->sh_entsize;
  77.          symbol_count++) {
  78.         current_symbol = symbol_ptr + symbol_count;
  79.         if (ELF32_ST_TYPE(current_symbol->st_info) != STT_FUNC &&
  80.         ELF32_ST_BIND(current_symbol->st_info) != STB_GLOBAL) {
  81.         continue;
  82.         }
  83.         if ((name = elf_strptr(elf_ptr, elf_str_index,
  84.                    (size_t)current_symbol->st_name)) == NULL) {
  85.         Free_Symbols(tab);
  86.         (void)close(lf);
  87.         Primitive_Error(elf_errmsg(elf_errno()));
  88.         }
  89.         sp = (SYM *)Safe_Malloc (sizeof (SYM));
  90.         sp->name = Safe_Malloc (strlen (name) + 1);
  91.         strcpy (sp->name, name);
  92.         sp->value = current_symbol->st_value;
  93.         *nextp = sp;
  94.         nextp = &sp->next;
  95.         *nextp = 0;
  96.     }
  97.     }
  98.     return tab;
  99. }
  100.   
  101. #ifdef INIT_OBJECTS
  102. SYMTAB *
  103. Open_File_And_Snarf_Symbols (name)
  104.      char *name;
  105. {
  106.     int        f;
  107.     SYMTAB    *tab;
  108.  
  109.     if ((f = open (name, O_RDONLY)) == -1)
  110.     Primitive_Error ("can't open a.out file");
  111.     tab = Snarf_Symbols (f);
  112.     (void)close(f);
  113.     return tab;
  114. }
  115. #endif /* INIT_OBJECTS */
  116.